package com.dubito.tmdbmovie.common

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.waitForUpOrCancellation
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.lazy.grid.LazyGridItemScope
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems
import java.io.IOException
import retrofit2.HttpException
import kotlin.time.Duration.Companion.minutes

fun <T : Any> LazyGridScope.items(
    lazyPagingItems: LazyPagingItems<T>,
    itemContent: @Composable LazyGridItemScope.(value: T?) -> Unit
) {
    items(lazyPagingItems.itemCount) { index ->
        itemContent(lazyPagingItems[index])
    }
}

@Composable
fun <T : Any> LazyPagingItems<T>.pagingLoadingState(
    isLoaded: (pagingState: Boolean) -> Unit,
    isAppend: (pagingState: Boolean) -> Unit,
    errorMsg: (String?) -> Unit
) {
    this.apply {
        when {
            // 首次加载数据
            loadState.refresh is LoadState.Loading -> {
                isLoaded(true)
                errorMsg("")
            }
            loadState.refresh is LoadState.Error -> {
                isLoaded(false)
                when (val error = (loadState.refresh as LoadState.Error).error) {
                    is IOException -> {
                        errorMsg(error.message)
                    }
                    is HttpException -> {
                        errorMsg(error.message)
                    }
                }
            }
            // 第二次加载数据 或者 分页加载 时候调用
            loadState.append is LoadState.Loading -> {
                isAppend(true)
                isLoaded(false)
                errorMsg("")
            }
            loadState.append is LoadState.Error -> {
                isAppend(false)
                when (val error = (loadState.append as LoadState.Error).error) {
                    is IOException -> {
                        errorMsg(error.message)
                    }
                    is HttpException -> {
                        errorMsg(error.message)
                    }
                }
            }
            loadState.refresh is LoadState.NotLoading -> {
                isLoaded(false)
                isAppend(false)
            }
            loadState.append is LoadState.NotLoading -> {
                isLoaded(false)
                isAppend(false)
            }

        }
    }
}

fun <T : Any> MutableState<DataState<T>?>.pagingLoadingState(isLoaded: (pagingState: Boolean) -> Unit) {
    when (this.value) {
        is DataState.Success<T> -> {
            isLoaded(false)
        }
        is DataState.Loading -> {
            isLoaded(true)
        }
        is DataState.Error -> {
            isLoaded(false)
        }
        else -> {

        }
    }
}

enum class ButtonState {
    Pressed, Idle
}

/**
 * 缩放效果
 */
fun Modifier.bounceClick() = composed {
    var buttonState by remember {
        mutableStateOf(ButtonState.Idle)
    }
    val scale by animateFloatAsState(targetValue = if (buttonState == ButtonState.Pressed) 0.7f else 1f)

    this
        .graphicsLayer {
            scaleX = scale
            scaleY = scale
        }
        .clickable(
            interactionSource = remember {
                MutableInteractionSource()
            },
            indication = null,
            onClick = {}
        )
        .pointerInput(buttonState) {
            awaitPointerEventScope {
                buttonState = if (buttonState == ButtonState.Pressed) {
                    waitForUpOrCancellation()
                    ButtonState.Idle
                } else {
                    awaitFirstDown(false)
                    ButtonState.Pressed
                }
            }
        }
}


object NavigationDefaults {
    val NavigationContainerColor = Color.Transparent
    @Composable
    fun navigationContentColor() = MaterialTheme.colorScheme.onSurfaceVariant
    @Composable
    fun navigationSelectedItemColor() = MaterialTheme.colorScheme.onPrimaryContainer
    @Composable
    fun navigationIndicatorColor() = MaterialTheme.colorScheme.primaryContainer
}

fun Int.hourMinutes(): String {
    return "${this.minutes.inWholeHours}h ${this % 60}m"
}

fun Int.genderInString(): String {
    return when (this) {
        1 -> "Female"
        2 -> "Male"
        else -> ""
    }
}
